package io.renren.controller;


import com.alipay.api.AlipayApiException;
import com.alipay.api.domain.AlipayTradeAppPayModel;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradeCreateRequest;
import com.alipay.api.response.AlipayTradeAppPayResponse;
import com.alipay.api.response.AlipayTradeCreateResponse;
import io.renren.common.utils.R;
import io.renren.config.AlipayConfig;
import io.renren.entity.ShopOrderEntity;
import io.renren.entity.TransationdetailEntity;
import io.renren.service.LinePasswordService;
import io.renren.service.ShopOrderService;
import io.renren.service.TransationdetailService;
import io.renren.service.UsersService;
import io.renren.utils.wxpay.*;

import net.sf.json.JSONObject;
import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;


import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.request.AlipayTradeAppPayRequest;


/**
 * 创建时间：2016年11月2日 下午4:16:32
 *
 * @author andy
 * @version 2.2
 */
@RestController
@RequestMapping("/order")
public class PayController {

    private static final String ORDER_PAY = "https://api.mch.weixin.qq.com/pay/unifiedorder"; // 统一下单


    private static final String APP_ID = ConfigUtil.getProperty("wx.appid");

    private static final String MCH_ID = ConfigUtil.getProperty("wx.mchid");

    private static final String API_SECRET = ConfigUtil.getProperty("wx.api.secret");
    private static final String URL ="https://dyc.ctolab.cn/renren-api/api";


    @Autowired
    LinePasswordService linePasswordService;

    @Autowired
    ShopOrderService shopOrderService;

    @Autowired
    UsersService usersService;

    @Autowired
    TransationdetailService transationdetailService;
    /**
     * 支付下订单
     * @param money
     * @param openid
     * 支付金额
     * 商品id
     *
     */
    public R orderPay(BigDecimal money,String openid,String time,int userid,int qcodeid,String ordersn) {


        Map<String, String> restmap = null;

        Map<String, String> body = new HashMap<>();
        body.put("money", money+"");
        body.put("time", time);
        body.put("ordersn", ordersn);
        body.put("userid", String.valueOf(userid));
        body.put("qcodeid", String.valueOf(qcodeid));

        boolean flag = true; // 是否订单创建成功
        try {

            String total_fee =money.multiply(BigDecimal.valueOf(100))
                    .setScale(0, BigDecimal.ROUND_HALF_UP).toString();
            System.out.println(total_fee);
            Map<String, String> parm = new HashMap<String, String>();
            parm.put("appid", APP_ID);
            parm.put("mch_id", MCH_ID);
            parm.put("device_info", "WEB");
            parm.put("nonce_str", PayUtil.getNonceStr());
            parm.put("body","共享充电支付");
            parm.put("attach", URLEncoder.encode(body.toString()));
            parm.put("out_trade_no", PayUtil.getTradeNo());
            parm.put("total_fee", total_fee);
            parm.put("spbill_create_ip", "127.0.0.1");
            parm.put("notify_url", URL+"/order/pay/notify");
            parm.put("trade_type", "JSAPI");
            parm.put("sign_type", "MD5");
            parm.put("openid", openid);
            parm.put("sign", PayUtil.getSign(parm, API_SECRET));
            String restxml = HttpUtils.post(ORDER_PAY, XmlUtil.xmlFormat(parm, false));

            System.out.println(restxml);
            restmap = XmlUtil.doXMLParse(restxml);
        } catch (Exception e) {
            e.getMessage();
        }
        Map<String, String> payMap = new HashMap<String, String>();
        if (CollectionUtil.isNotEmpty(restmap) && "SUCCESS".equals(restmap.get("result_code"))) {

            payMap.put("appId", APP_ID);
            payMap.put("signType", "MD5");
            payMap.put("package", "prepay_id="+restmap.get("prepay_id"));

            payMap.put("nonceStr", PayUtil.getNonceStr());

            payMap.put("timeStamp", PayUtil.payTimestamp());

            try {
                payMap.put("sign", PayUtil.getSign(payMap, API_SECRET));
            } catch (Exception e) {
                flag = false;
            }
        }
        if (flag) {

                    return R.ok("订单获取成功").put("payMap",payMap).put("ordersn",ordersn);
        } else {
            if (CollectionUtil.isNotEmpty(restmap)) {
                System.out.println("订单创建失败：" + restmap.get("err_code") + ":" + restmap.get("err_code_des"));
                return R.error(210,"订单创建失败：" + restmap.get("err_code") + ":" + restmap.get("err_code_des"));
            }

            return R.error(-1,"订单获取失败：");
        }
    }



    /**
     * 订单支付微信服务器异步通知
     *
     * @param request
     * @param response
     */
    @RequestMapping("/pay/notify")
    public void orderPayNotify(HttpServletRequest request, HttpServletResponse response) {
        response.setCharacterEncoding("UTF-8");
        response.setContentType("text/xml");
        System.out.println("进入回调方法===============================================");
        try {
            ServletInputStream in = request.getInputStream();
            String resxml = FileUtil.readInputStream2String(in);
            Map<String, String> restmap = XmlUtil.doXMLParse(resxml);
            System.out.println("=======================支付结果通知：" + restmap);
            if ("SUCCESS".equals(restmap.get("result_code"))) {

                // 通过商户订单判断是否该订单已经处理 如果处理跳过 如果未处理先校验sign签名 再进行订单业务相关的处理
                String sing = restmap.get("sign"); // 返回的签名
                restmap.remove("sign");
                String signnow = PayUtil.getSign(restmap, API_SECRET);
                if (signnow.equals(sing)) {

                } else {
                    System.out.println("订单支付通知：签名错误");
                }
            } else {
                System.out.println("订单支付通知：支付失败，" + restmap.get("err_code") + ":" + restmap.get("err_code_des"));
            }
        } catch (Exception e) {
            System.out.println(e.getMessage()+e);
        }
    }


    /**
     * 我的充值
     * @param money 充值金额
     * @param userid  用户id
     *
     *
     */
    public R ourRecharge(BigDecimal money,int userid,String openid) {

        Map<String, String> restmap = null;


        Map<String, String> body = new HashMap<>();
        body.put("money", money+"");
        body.put("userid", String.valueOf(userid));

        boolean flag = true; // 是否充值验签成功
        try {

            String total_fee =money.multiply(BigDecimal.valueOf(100))
                    .setScale(0, BigDecimal.ROUND_HALF_UP).toString();
            System.out.println(total_fee);
            Map<String, String> parm = new HashMap<String, String>();
            parm.put("appid", APP_ID);
            parm.put("mch_id", MCH_ID);
            parm.put("device_info", "WEB");
            parm.put("nonce_str", PayUtil.getNonceStr());
            parm.put("body","共享充电充值");
            parm.put("attach", URLEncoder.encode(body.toString()));
            parm.put("out_trade_no", PayUtil.getTradeNo());
            parm.put("total_fee", total_fee);
            parm.put("spbill_create_ip", "127.0.0.1");
            parm.put("notify_url", URL+"/order/pay/recharge");
            parm.put("trade_type", "JSAPI");
            parm.put("sign_type", "MD5");
            parm.put("openid", openid);
            parm.put("sign", PayUtil.getSign(parm, API_SECRET));
            String restxml = HttpUtils.post(ORDER_PAY, XmlUtil.xmlFormat(parm, false));

            System.out.println(restxml);
            restmap = XmlUtil.doXMLParse(restxml);
        } catch (Exception e) {
            e.getMessage();
        }
        Map<String, String> payMap = new HashMap<String, String>();
        if (CollectionUtil.isNotEmpty(restmap) && "SUCCESS".equals(restmap.get("result_code"))) {

            payMap.put("appId", APP_ID);
            payMap.put("signType", "MD5");
            payMap.put("package", "prepay_id="+restmap.get("prepay_id"));

            payMap.put("nonceStr", PayUtil.getNonceStr());

            payMap.put("timeStamp", PayUtil.payTimestamp());

            try {
                payMap.put("sign", PayUtil.getSign(payMap, API_SECRET));
            } catch (Exception e) {
                flag = false;
            }
        }
        if (flag) {

            return R.ok().put("payMap",payMap);
        } else {
            if (CollectionUtil.isNotEmpty(restmap)) {
                System.out.println("充值验签失败：" + restmap.get("err_code") + ":" + restmap.get("err_code_des"));
                return R.error(210,"充值验签失败：" + restmap.get("err_code") + ":" + restmap.get("err_code_des"));
            }

            return R.error(-1,"充值验签失败：");
        }
    }

    /**
     * 充值回调
     *
     * @param request
     * @param response
     */
    @RequestMapping("/pay/recharge")
    public void recharge(HttpServletRequest request, HttpServletResponse response) {
        response.setCharacterEncoding("UTF-8");
        response.setContentType("text/xml");
        try {
            ServletInputStream in = request.getInputStream();
            String resxml = FileUtil.readInputStream2String(in);
            Map<String, String> restmap = XmlUtil.doXMLParse(resxml);
            System.out.println("=======================充值结果通知：" + restmap);
            if ("SUCCESS".equals(restmap.get("result_code"))) {

                // 通过商户订单判断是否该订单已经处理 如果处理跳过 如果未处理先校验sign签名 再进行订单业务相关的处理
                String sing = restmap.get("sign"); // 返回的签名
                restmap.remove("sign");
                String signnow = PayUtil.getSign(restmap, API_SECRET);
                if (signnow.equals(sing)) {

                } else {
                    System.out.println("充值通知：签名错误");
                }
            } else {
                System.out.println("充值通知：支付失败，" + restmap.get("err_code") + ":" + restmap.get("err_code_des"));
            }
        } catch (Exception e) {
            System.out.println(e.getMessage()+e);
        }
    }

    /**
     *
     * @param outTradeNo  商户订单号，商户网站订单系统中唯一订单号，必填   对应缴费记录的orderNo
     * @param totalAmount  付款金额，必填
     * @param subject 主题
     * @param body 商品描述，可空
     * @return
     */
    public R alipaySign(String outTradeNo,String totalAmount,String subject,String body,String openid) {
        //获得初始化的AlipayClient
        AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.gatewayUrl, AlipayConfig.app_id, AlipayConfig.merchant_private_key, "json", AlipayConfig.charset, AlipayConfig.alipay_public_key, AlipayConfig.sign_type);

        //实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称：alipay.trade.create.
        AlipayTradeCreateRequest alipayRequest = new AlipayTradeCreateRequest();

        alipayRequest.setReturnUrl(AlipayConfig.return_url);
        alipayRequest.setNotifyUrl(AlipayConfig.notify_url);

        String content = "{\"out_trade_no\":\""+outTradeNo+"\",\"total_amount\":"+totalAmount+",\"subject\":\""+subject+"\",\"buyer_id\":\""+openid+"\"}";
        /*//sdk中的model入参
        AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
        model.setPassbackParams(body);      //描述信息，添加附加数据
        model.setSubject(subject);          //商品标题
        model.setOutTradeNo(outTradeNo);  //订单号
        model.setTimeoutExpress("30m");     //超时关闭该订单时间
        model.setTotalAmount(totalAmount);     //将double数值转换成String类
        model.setProductCode("FAST_INSTANT_TRADE_PAY");*/

        alipayRequest.setBizContent(content);
        String orderStr = "";
        AlipayTradeCreateResponse response = null;

        try {
            response = alipayClient.execute(alipayRequest);
            orderStr = response.getBody();
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }

        String sign = DigestUtils.md5Hex(outTradeNo).toUpperCase();

        /////////////////处理你自己的逻辑/////////////////////////

        JSONObject resObj = new JSONObject();
        resObj.put("code", "SUCCESS");
        resObj.put("out_trade_no", outTradeNo);
        resObj.put("trade_no", response.getTradeNo());
        resObj.put("sign", sign);
        resObj.put("orderStr",orderStr);
        System.out.println(resObj.toString());
        return R.ok().put("sign",resObj);
    }


    /**
     * 支付宝回调
     * @param request
     * @return
     */
    @ResponseBody
    @RequestMapping(value="/alipayNotify",method= RequestMethod.POST)
    public String alipayNotify(HttpServletRequest request){
        Map requestParams = request.getParameterMap();

        //获取支付宝POST过来反馈信息
        Map<String,String> params = new HashMap<String,String>();

        for(Iterator iter = requestParams.keySet().iterator(); iter.hasNext();){
            String name = (String)iter.next();
            String[] values = (String[]) requestParams.get(name);
            String valueStr= "";
            for(int i=0;i < values.length;i++){
                valueStr = (i == values.length - 1) ? valueStr + values[i]
                        : valueStr + values[i] + ",";

                //乱码解决，这段代码在出现乱码时使用。
                //valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
                params.put(name, valueStr);
            }
        }

        ///////////////////处理自己的逻辑//////////////////////

        try {
            boolean flag = AlipaySignature.rsaCheckV1
                    (params, AlipayConfig.alipay_public_key, "UTF-8", "RSA2");
            if(flag){
                if("TRADE_SUCCESS".equals(params.get("trade_status"))){
                    String ordersn = params.get("out_trade_no");
                    ShopOrderEntity shopOrderEntity = shopOrderService.getShopOrderByOrderSn(ordersn);
                    if(shopOrderEntity!=null){

                    }else{
                        return "ERROR";
                    }
                }

            }
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        return "SUCCESS";
    }

    /**
     * 支付宝充值
     * @param outTradeNo  商户订单号，商户网站订单系统中唯一订单号，必填   对应缴费记录的orderNo
     * @param totalAmount  付款金额，必填
     * @param subject 主题
     * @param body 商品描述，可空
     * @return
     */
    public R alipayCashSign(String outTradeNo,String totalAmount,String subject,String body,String openid) {
        //获得初始化的AlipayClient
        AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.gatewayUrl, AlipayConfig.app_id, AlipayConfig.merchant_private_key, "json", AlipayConfig.charset, AlipayConfig.alipay_public_key, AlipayConfig.sign_type);

        //实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称：alipay.trade.create.
        AlipayTradeCreateRequest alipayRequest = new AlipayTradeCreateRequest();

        alipayRequest.setReturnUrl(AlipayConfig.return_url);
        alipayRequest.setNotifyUrl(AlipayConfig.notify_url);

        String content = "{\"out_trade_no\":\""+outTradeNo+"\",\"total_amount\":"+totalAmount+",\"subject\":\""+subject+"\",\"buyer_id\":\""+openid+"\"}";
        /*//sdk中的model入参
        AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
        model.setPassbackParams(body);      //描述信息，添加附加数据
        model.setSubject(subject);          //商品标题
        model.setOutTradeNo(outTradeNo);  //订单号
        model.setTimeoutExpress("30m");     //超时关闭该订单时间
        model.setTotalAmount(totalAmount);     //将double数值转换成String类
        model.setProductCode("FAST_INSTANT_TRADE_PAY");*/

        alipayRequest.setBizContent(content);
        String orderStr = "";
        AlipayTradeCreateResponse response = null;

        try {
            response = alipayClient.execute(alipayRequest);
            orderStr = response.getBody();
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }

        String sign = DigestUtils.md5Hex(outTradeNo).toUpperCase();

        /////////////////处理你自己的逻辑/////////////////////////

        JSONObject resObj = new JSONObject();
        resObj.put("code", "SUCCESS");
        resObj.put("out_trade_no", outTradeNo);
        resObj.put("trade_no", response.getTradeNo());
        resObj.put("sign", sign);
        resObj.put("orderStr",orderStr);
        System.out.println(resObj.toString());
        return R.ok().put("sign",resObj);
    }
}